package com.start.oss;

import com.start.common.entity.StartDicData;
import com.start.common.exceptions.StartBusException;
import com.start.oss.entity.StartSysOssEntity;
import com.start.oss.exceptions.StartOssNotFound;
import com.start.oss.filters.StartOSSFilter;
import com.start.oss.service.StartSysOssService;
import com.start.oss.storage.StartOssStorageService;
import org.apache.commons.lang3.StringUtils;

import java.util.*;

public class StartOssWrapper implements StartOssService {

    private final List<StartOSSFilter> filters;
    private final Map<String, StartOssStorageService> ossStorageServiceMap;
    private final String defaultStorageType;
    private final StartSysOssService startSysOssService;

    public StartOssWrapper(Map<String, StartOssStorageService> ossStorageServiceMap,
                           List<StartOSSFilter> filters,
                           StartSysOssService startSysOssService,
                           String defaultStorageType) {
        this.filters = filters;
        this.ossStorageServiceMap = new HashMap<>();
        ossStorageServiceMap.values().forEach((e) -> {
            this.ossStorageServiceMap.put(e.getOssTypeKey(), e);
        });
        this.defaultStorageType = defaultStorageType;
        this.startSysOssService = startSysOssService;
    }

    @Override
    public final StartSysOssEntity add(StartOssData data) {
        if (data == null) {
            return null;
        }
        if (filters != null && filters.size() > 0) {
            for (StartOSSFilter filter : filters) {
                filter.uploadFilter(data);
            }
        }
        long size = data.getFile().getSize();
        final StartSysOssEntity ossEntity = save(data);
        ossEntity.setOssSize(size);
        ossEntity.setOssMimeType(data.getFile().getContentType());
        ossEntity.setOssAccessType(data.getAccessType());
        ossEntity.setOssAutoRename(data.isAutoRename());
        startSysOssService.save(ossEntity);
        return ossEntity;
    }

    /**
     * 保存对象
     *
     * @param data 对象
     * @return StartSysOssEntity
     */
    public final StartSysOssEntity save(StartOssData data) {
        if (StringUtils.isEmpty(data.getFile().getOriginalFilename())) {
            throw new StartBusException("文件名称不能为空");
        }
        final StartOssStorageService storage = getStorage(data.getOssStorageType());
        final StartSysOssEntity ossEntity = storage.save(data);
        if (ossEntity == null) {
            throw new StartOssNotFound("", "文件上传失败 " + storage.getOssTypeKey() + "save 返回值不能为空");
        }
        ossEntity.setOssStorageType(storage.getOssTypeKey());
        return ossEntity;
    }


    /**
     * 获取文件夹
     *
     * @param url 文件地址
     * @return byte[]
     */
    @Override
    public byte[] getPath(String url) {
        final StartSysOssEntity ossEntity = startSysOssService.getByPath(url);
        if (ossEntity == null) {
            throw new StartOssNotFound(url);
        }
        final StartOssStorageService storage = getStorage(ossEntity.getOssStorageType());
        final byte[] bytes = storage.getByOssEntity(ossEntity);
        if (bytes == null || bytes.length < 1) throw new StartOssNotFound(url);
        return bytes;
    }

    @Override
    public byte[] getById(String id) {
        final StartSysOssEntity ossEntity = startSysOssService.getById(id);
        if (ossEntity == null) throw new StartOssNotFound(id);
        final StartOssStorageService storage = getStorage(ossEntity.getOssStorageType());
        final byte[] bytes = storage.getOssBySysOssEntity(ossEntity);
        if (bytes == null || bytes.length < 1) throw new StartOssNotFound(id);
        return bytes;
    }



    @Override
    public boolean remove(String id) {
        final StartSysOssEntity ossEntity = startSysOssService.getById(id);
        if (ossEntity == null) return true;
        startSysOssService.removeById(id);
        final StartOssStorageService storage = getStorage(ossEntity.getOssStorageType());
        return storage.remove(ossEntity);
    }

    /**
     * 获取全部存储器类型
     *
     * @return
     */
    @Override
    public List<StartDicData> getAllStorage() {
        Collection<StartOssStorageService> services = ossStorageServiceMap.values();
        List<StartDicData> result = new ArrayList<>();
        for (StartOssStorageService storageService : services) {
            result.add(
                    new StartDicData(StringUtils.isNoneEmpty(
                            storageService.getOssLabel()) ? storageService.getOssLabel() : storageService.getOssTypeKey(),
                            storageService.getOssTypeKey()
                    )
            );
        }
        return result;
    }


    public final StartOssStorageService getStorage(String storageType) {
        if (ossStorageServiceMap == null || ossStorageServiceMap.size() < 1) {
            throw new StartBusException("未配置任何对象存储器");
        }
        if (StringUtils.isEmpty(storageType)) {
            storageType = defaultStorageType;
        }
        if (StringUtils.isEmpty(storageType)) {
            throw new StartBusException("未配置默认存储器");
        }
        final StartOssStorageService storageService = ossStorageServiceMap.getOrDefault(storageType, null);
        if (storageService == null) {
            throw new StartBusException("未找到类型为：" + storageType + " 的对象存储器");
        }
        return storageService;
    }


}
